<!DOCTYPE html>
<html>
<head>
    <title>Nuclear Energy Level Diagram of 20Ne</title>
</head>
<body>
    <canvas id="physicsCanvas" width="700" height="550"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // --- Configuration ---
        const config = {
            font: '16px Arial',
            lineWidth: 1.5,
            colors: {
                line: 'black',
                text: 'black'
            },
            // Energy scale (in MeV)
            energyMax: 12.0,
            yMin: 40,
            yMax: 500,
            // Horizontal positions
            level: {
                x_left: 250,
                x_right: 450,
                x_label_left: 240,
                x_label_right: 460
            },
            alpha: {
                x_left: 50,
                x_right: 180,
                x_label_left: 60,
                x_label_right: 190
            }
        };

        // --- Helper Functions ---
        function energyToY(energy) {
            const { energyMax, yMin, yMax } = config;
            return yMax - (energy / energyMax) * (yMax - yMin);
        }

        function drawLine(x1, y1, x2, y2) {
            ctx.beginPath();
            ctx.moveTo(x1, y1);
            ctx.lineTo(x2, y2);
            ctx.stroke();
        }

        function drawText(text, x, y, align = 'left', baseline = 'middle') {
            ctx.textAlign = align;
            ctx.textBaseline = baseline;
            ctx.fillText(text, x, y);
        }

        function drawArrow(x1, y1, x2, y2, size = 8) {
            const angle = Math.atan2(y2 - y1, x2 - x1);
            ctx.beginPath();
            ctx.moveTo(x2, y2);
            ctx.lineTo(x2 - size * Math.cos(angle - Math.PI / 6), y2 - size * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(x2, y2);
            ctx.lineTo(x2 - size * Math.cos(angle + Math.PI / 6), y2 - size * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        function drawDashedLineWithMidArrow(x1, y1, x2, y2, dash, size) {
            // Draws a dashed line from (x1,y1) to (x2,y2)
            // with an arrowhead in the middle, pointing towards (x2, y2)
            ctx.setLineDash(dash);
            drawLine(x1, y1, x2, y2);
            ctx.setLineDash([]);

            const midX = (x1 + x2) / 2;
            const midY = (y1 + y2) / 2;
            const angle = Math.atan2(y2 - y1, x2 - x1);
            // Position the arrow centered at the midpoint
            const arrow_base_x = midX - (size / 2) * Math.cos(angle);
            const arrow_base_y = midY - (size / 2) * Math.sin(angle);
            const arrow_tip_x = midX + (size / 2) * Math.cos(angle);
            const arrow_tip_y = midY + (size / 2) * Math.sin(angle);
            
            drawArrow(arrow_base_x, arrow_base_y, arrow_tip_x, arrow_tip_y, size);
        }

        // --- Main Drawing Function ---
        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.strokeStyle = config.colors.line;
            ctx.fillStyle = config.colors.text;
            ctx.lineWidth = config.lineWidth;
            ctx.font = config.font;

            const { level, alpha } = config;
            
            // Unicode characters for superscripts and symbols
            const sup_plus = '\u207A';
            const sup_minus = '\u207B';
            const sup_0 = '\u2070';
            const sup_1 = '\u00B9';
            const sup_2 = '\u00B2';
            const sup_3 = '\u00B3';
            const sup_6 = '\u2076';
            const sup_9 = '\u2079';
            const char_alpha = '\u03B1';

            // --- Draw 20Ne Levels ---
            const y_gnd = energyToY(0);
            const y_top = energyToY(10.890);
            // Bounding box for levels
            drawLine(level.x_left, y_gnd, level.x_left, y_top - 10);
            drawLine(level.x_right, y_gnd, level.x_right, y_top - 10);

            // Ground state 0+
            const y_0plus = energyToY(0);
            drawLine(level.x_left, y_0plus, level.x_right, y_0plus);
            drawText('0' + sup_plus, level.x_label_left, y_0plus, 'right');
            drawText('0', level.x_label_right, y_0plus, 'left');

            // 2+ state
            const y_2plus = energyToY(1.63);
            drawLine(level.x_left, y_2plus, level.x_right, y_2plus);
            drawText('2' + sup_plus, level.x_label_left, y_2plus, 'right');
            drawText('1.63', level.x_label_right, y_2plus, 'left');

            // Many levels section
            const many_levels_E = [5.6, 6.1, 6.7, 7.1]; // Approximate energies from image
            for (const E of many_levels_E) {
                const y = energyToY(E);
                drawLine(level.x_left, y, level.x_right, y);
            }
            
            // Draw brace for "many levels"
            const brace_y1 = energyToY(10.5);
            const brace_y2 = energyToY(5.0);
            const brace_x = level.x_right + 10;
            const brace_w = 15;
            const midY_brace = (brace_y1 + brace_y2) / 2;

            ctx.beginPath();
            ctx.moveTo(brace_x, brace_y1);
            ctx.bezierCurveTo(brace_x + brace_w, brace_y1, brace_x + brace_w, midY_brace, brace_x, midY_brace);
            ctx.bezierCurveTo(brace_x + brace_w, midY_brace, brace_x + brace_w, brace_y2, brace_x, brace_y2);
            ctx.stroke();
            drawText('many levels', brace_x + brace_w + 5, midY_brace, 'left');

            // 3- T=0 state
            const y_3minus = energyToY(10.838);
            drawLine(level.x_left, y_3minus, level.x_right, y_3minus);
            drawText('3' + sup_minus + ' T = 0', level.x_label_left, y_3minus, 'right');
            drawText('10.838', level.x_label_right, y_3minus, 'left');

            // 3+ T=1 state
            const y_3plus = energyToY(10.890);
            drawLine(level.x_left, y_3plus, level.x_right, y_3plus);
            drawText('3' + sup_plus + ' T = 1', level.x_label_left, y_3plus, 'right');
            drawText('10.890', level.x_label_right, y_3plus, 'left');
            
            // Bottom label
            drawText(sup_2 + sup_0 + 'Ne', (level.x_left + level.x_right)/2, y_0plus + 25, 'center');

            // --- Draw 16O + alpha threshold ---
            const y_alpha = energyToY(4.730);
            drawLine(alpha.x_left, y_alpha, alpha.x_right, y_alpha);
            drawText(sup_1 + sup_6 + 'O + ' + char_alpha, alpha.x_left, y_alpha, 'left');
            drawText('4.730', alpha.x_right, y_alpha, 'left');

            // --- Draw arrows from alpha channel ---
            // Upper arrow (to 3+ state)
            const upper_start_x = alpha.x_right - 40;
            const upper_end_x = level.x_left;
            drawDashedLineWithMidArrow(upper_start_x, y_alpha, upper_end_x, y_3plus, [4, 4], 8);

            // Lower arrow (to 3- state)
            const lower_start_x = alpha.x_right - 20;
            const lower_end_x = level.x_left;
            drawDashedLineWithMidArrow(lower_start_x, y_alpha, lower_end_x, y_3minus, [4, 4], 8);

            // --- Draw reaction thresholds on the right ---
            const reaction_label_x_start = level.x_right + 40;
            const reaction_line_end = reaction_label_x_start + 115;
            
            // 19F + 3He - d
            const y_he3d = energyToY(7.350);
            drawText(sup_1 + sup_9 + 'F + ' + sup_3 + 'He - d', reaction_label_x_start, y_he3d - 5, 'left', 'bottom');
            drawLine(reaction_label_x_start, y_he3d, reaction_line_end, y_he3d);
            drawText('7.350', reaction_line_end + 5, y_he3d, 'left');
            
            // 19F + d - n
            const y_dn = energyToY(10.620);
            drawText(sup_1 + sup_9 + 'F + d - n', reaction_label_x_start, y_dn - 5, 'left', 'bottom');
            drawLine(reaction_label_x_start, y_dn, reaction_line_end, y_dn);
            drawText('10.620', reaction_line_end + 5, y_dn, 'left');

            // --- Final caption ---
            drawText('Fig. 2.29', canvas.width / 2, canvas.height - 15, 'center');
        }

        draw();
    </script>
</body>
</html>